#include<iostream>
#include<string>
#include<ctype.h>
#include "SplitDeclaration.h"

using namespace std;

QRYSTATEMENT_TYPE SplitDeclaration::splitDeclaration(QueryEvaluator& obj, string decl, COLLECTION& declVector)
{
	if(decl.compare("")==0)
		return _EMPTY;

	string temp;
	QRYSTATEMENT_TYPE asstType=_INVALID;
	COLLECTION type,vars, statements;
	bool var_type=true;
	char *cstr, *p;

	boost::trim(decl);

    cstr = new char [decl.size()+1];
	strcpy (cstr, decl.c_str());

	p=strtok (cstr,";");

	while (p!=NULL)
	{	
		temp=p;
		
		statements.push_back(temp);
		
		p=strtok(NULL,";");
	}

	for(unsigned int i=0;i<statements.size();i++)
	{
		asstType=splitStatement(statements.at(i),declVector);
		
		if(asstType==_INVALID || asstType==_KEYWORDS)
		{
			return _INVALID;
		}

		else{
			obj.generateMapping(asstType,declVector);
			declVector.clear();
		}
			
		
	}

	return asstType;

}
QRYSTATEMENT_TYPE SplitDeclaration::splitStatement(string statements, COLLECTION& declVector)
{
	string temp2;
	QRYSTATEMENT_TYPE asstType=_INVALID, temp;
	string type;
	char *c_str, *q, *temptype;

	c_str = new char [statements.size()+1];
	strcpy (c_str, statements.c_str());

	q=strtok (c_str," ,");

	temptype=q;
	q=strtok(NULL," ,");

	while (q!=NULL)
	{
		temp2=q;
		temp = checkType(temp2);
		if(temp==_INVALID)
			declVector.push_back(temp2);
		else 
			return _INVALID;
		q=strtok(NULL," ,");

	}
	
	for(int i=0;temptype[i]!='\0';i++)
		if(isalpha(temptype[i]))
			temptype[i]=tolower(temptype[i]);

	type=temptype;

	asstType = checkType(type);

	return asstType;

}

QRYSTATEMENT_TYPE SplitDeclaration::checkType(string type)
{
	QRYSTATEMENT_TYPE asstType=_INVALID;

	vector<string> keyWords;

	keyWords.push_back("select");
	keyWords.push_back("such");
	keyWords.push_back("that");
	keyWords.push_back("and");
	keyWords.push_back("with");
	keyWords.push_back("follows");
	keyWords.push_back("follows*");
	keyWords.push_back("parent");
	keyWords.push_back("parent*");
	keyWords.push_back("modifies");
	keyWords.push_back("uses");
	keyWords.push_back("next");
	keyWords.push_back("next*");
	keyWords.push_back("affects");
	keyWords.push_back("affects*");
	keyWords.push_back("pattern");
	keyWords.push_back("calls");
	keyWords.push_back("calls*");
	keyWords.push_back("value");

	if(!type.compare("assign"))
	{
		asstType=_ASSIGN;
	}

	else if(!type.compare("call"))
	{
		asstType=_CALL;
	}

	else if(!type.compare("if"))
	{
		asstType=_IF;
	}

	else if(!type.compare("while"))
	{
		asstType=_WHILE;
	}
	
	else if(!type.compare("procedure"))
	{
		asstType=_PROCEDURE;
	}

	else if(!type.compare("stmtList"))
	{
		asstType=_STMTLIST;
	}

	else if(!type.compare("stmt"))
	{
		asstType=_STMT;
	}

	else if(!type.compare("variable"))
	{
		asstType=_VARIABLE;
	}

	else if(!type.compare("constant"))
	{
		asstType=_CONSTANT;
	}

	else if(!type.compare("INTEGER"))
	{
		asstType=_INTEGER;
	}

	else if(!type.compare("synonyms"))
	{
		asstType=_SYNONYMNS;
	}

	else if(!type.compare("prog_line"))
	{
		asstType=_PROGLINE;
	}

	else
	{
		for(unsigned int i=0;i<keyWords.size();i++)
			if(!type.compare(keyWords.at(i)))
				asstType=_KEYWORDS;
			
		if(asstType!=_KEYWORDS)
			asstType=_INVALID;
	}

	return asstType;

}
